///////////////////////////////////////////////////////////////////////////
//
// Spring Engine Source File.
// Copyright (C), Dengtao 2011-2021
// ----------------------------------------------------------------------
// File name:   SfMessage.h
// Version:     v1.0.0
// Created:     2013/06/16 19:44 by dengtao
// Compilers:   Visual Studio 2008
// Description: 
// ----------------------------------------------------------------------
// History:
//
///////////////////////////////////////////////////////////////////////////

#ifndef _SfMessage_H_
#define _SfMessage_H_

#include "SfGameObjectGUID.h"
#include "SfRefObject.h"
#include "SfSmartPtr.h"

namespace Sunflower
{

class GameObject;

//////////////////////////////////////////////////////////////////////////
//Summary:
//	Message Argument.
//////////////////////////////////////////////////////////////////////////
class MessageArgument : public RefObject
{
public:
	////
	////Summary:
	//virtual MessageArgument* Clone() 
	//{
	//	SfAssert(false);
	//	return SfNew MessageArgument();
	//}
};

SfDeclareSmartPtr(MessageArgument);

//////////////////////////////////////////////////////////////////////////
//Summary:
//	Message for communication between game objects.
class Message
{
public:
	//
	//Summary:
	//	enum invalid message id
	enum 
	{
		InvalidMessageId = 0,
	};

public:
	//
	//Summary:
	//	constructor.
	Message()
		: TimeStamp(0.0f)
	{
	}

	Message(unsigned int msgId, const GameObjectGUID& senderId, const GameObjectGUID& recieverId,
			MessageArgument* arg, float timeStamp = 0.0f)
	{
		MsgID = msgId;
		Sender.Goid = senderId;
		Reciever.Goid = recieverId;
		Argument = arg;
		TimeStamp = timeStamp;
	}

	Message(unsigned int msgId, GameObject* senderPtr, GameObject* recieverPtr,
		MessageArgument* arg, float timeStamp = 0.0f)
	{
		MsgID = msgId;
		Sender.ObjectPtr = senderPtr;

		//if (SfIsValidPtr(senderPtr))
		//{
		//	Sender.Goid = senderPtr->GetGoid();
		//}

		Reciever.ObjectPtr = recieverPtr;

		//if (SfIsValidPtr(recieverPtr))
		//{
		//	Reciever.Goid = recieverPtr->GetGoid();
		//}

		Argument = arg;
		TimeStamp = timeStamp;
	}

	Message(const Message& other)
		: MsgID(other.MsgID)
		, Sender(other.Sender)
		, Reciever(other.Reciever)
		, Argument(other.Argument)
		, TimeStamp(other.TimeStamp)
	{
	}

	//
	//Summary:
	//	destructor.
	~Message(){}

public:
	struct ObjectInfo
	{
		ObjectInfo()
			: ObjectPtr(SfNull)
		{
		}

		ObjectInfo(const ObjectInfo& other)
		{
			ObjectPtr = other.ObjectPtr;
			Goid = other.Goid;
		}

		ObjectInfo& operator =(const ObjectInfo& other)
		{
			ObjectPtr = other.ObjectPtr;
			Goid = other.Goid;

			return *this;
		}

		GameObject* ObjectPtr;
		GameObjectGUID Goid;
	};

	unsigned int MsgID;
	ObjectInfo Sender;
	ObjectInfo Reciever;
	float TimeStamp;
	MessageArgumentPtr Argument;
};

}

#endif
